import grpc
from random import randint
from common.utils.id_util import uuid
from common.utils.etcd_util import get_etcd_client
import json

__connect_pool = {

}


def init_connect_pool(service_name, service_id, host, port, count=10):
    exist_count = 0
    if service_name not in __connect_pool:
        __connect_pool[service_name] = []
    else:
        conns = __connect_pool[service_name]
        for c in conns:
            if c['service_id'] == service_id:
                exist_count += 1

    for i in range(count - exist_count):
        conn = grpc.insecure_channel(host + ':' + port)
        conn_id = uuid()
        __connect_pool[service_name].append({
            'conn_id': conn_id,
            'service_id': service_id,
        })
        __connect_pool[conn_id] = conn


def get_connect(service_name):
    if service_name in __connect_pool:
        count = len(__connect_pool[service_name])
        if count == 0:
            del __connect_pool[service_name]
            return get_connect(service_name)
        index = randint(0, count - 1)
        conn_id = __connect_pool[service_name][index]['conn_id']
        if conn_id not in __connect_pool:
            del __connect_pool[service_name][index]
            return get_connect(service_name)

        return conn_id, __connect_pool[conn_id]
    else:
        client = get_etcd_client()
        try:
            services = json.loads(client.get(service_name).value)
            if not services:
                return None, None
        except BaseException as e:
            print(e)
            return None, None
        for s in services:
            try:
                info = client.get(s).value
                info = json.loads(info)
                init_connect_pool(service_name=service_name, service_id=s, host=info['host'], port=info['port'])
            except Exception as e:
                services.remove(s)
                client.set(service_name, json.dumps(services, ensure_ascii=False))

        return get_connect(service_name)


def delete_connect(service_name, service_id):
    if service_name in __connect_pool:
        conns = __connect_pool[service_name]
        for c in conns:
            if c['service_id'] == service_id:
                del c['conn_id']
                conns.remove(c)


def destroy_connect(conn_id):
    if conn_id in __connect_pool:
        del __connect_pool[conn_id]

